﻿using System;
using System.IO;
using System.ServiceModel;
using System.Windows.Forms;
using System.Collections.Generic;
using ajayumi.develop.win32.Transport.Utils.WinForm;
using ajayumi.develop.win32.Transport.WCF.Services;
using ajayumi.develop.win32.Transport.WCF.ServiceImpls;
using ajayumi.develop.win32.Transport.Utils;


namespace ajayumi.develop.win32.Transport.Server.WinForm
{

    /// <summary>
    /// Author  : 黄乙冬
    /// Date    : 2011-08-28
    /// </summary>
    public partial class FrmMain : Form
    {
        #region Variables

        private readonly FailureDialog m_FailureDlg = null;


        private List<ServiceHost> m_Services = null;
        private TransFileCollection m_UploadFileCollection = new TransFileCollection();
        private TransFileCollection m_DownloadFileCollection = new TransFileCollection();

        #endregion

        public FrmMain()
        {
            InitializeComponent();

            ControlHelper.DoubleBuffered(this.dgvUploadFiles, true);
            ControlHelper.DoubleBuffered(this.dgvDownloadFiles, true);
            this.dgvUploadFiles.AutoGenerateColumns = false;
            this.dgvDownloadFiles.AutoGenerateColumns = false;

            this.Load += (sender, e) =>
            {
                this.dgvUploadFiles.DataSource = this.m_UploadFileCollection;
                this.dgvDownloadFiles.DataSource = this.m_DownloadFileCollection;

                this.Start();
            };

            this.m_FailureDlg = new FailureDialog();
        }

        #region 私有方法定义

        /// <summary>
        /// 设置文本值
        /// </summary>
        /// <param name="control"></param>
        /// <param name="text"></param>
        public void SetText(ToolStripStatusLabel control, string text)
        {
            if (this.StatusStrip1.InvokeRequired)
            {
                this.StatusStrip1.Invoke(new Action<ToolStripStatusLabel, string>(this.SetText), new object[] { control, text });
            }
            else
            {
                control.Text = text;
            }
        }

        /// <summary>
        /// 追加反馈信息
        /// </summary>
        /// <param name="control"></param>
        /// <param name="text"></param>
        private void AppendText(TextBox control, string text)
        {
            if (control.InvokeRequired)
            {
                try
                {
                    control.Invoke(new Action<TextBox, string>(this.AppendText), new object[] { control, text });
                }
                catch (Exception)
                { }
            }
            else
            { control.AppendText(text); }
        }

        /// <summary>
        /// 获得保存目录
        /// </summary>
        /// <returns></returns>
        public string GetSaveDir()
        {
            return AppConfig.SaveDir;
        }

        /// <summary>
        /// 获取缓存大小
        /// </summary>
        /// <returns></returns>
        public int GetBufSize()
        {
            return AppConfig.BufferSize;
        }

        /// <summary>
        /// 开启服务
        /// </summary>
        private void Start()
        {
            this.InitServices();
            this.m_Services.ForEach((service) =>
            {
                if (service.BaseAddresses.Count > 0)
                {
                    service.Open();
                }
            });

            this.SetText(this.tsslbStauts, "服务已启动");

            this.tsmiStart.Enabled = false;
            this.tsmiStop.Enabled = true;
            this.tsmiStart2.Enabled = false;
            this.tsmiStop2.Enabled = true;
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        private void Stop()
        {
            this.m_Services.ForEach((service) =>
            {
                if (service.BaseAddresses.Count > 0)
                {
                    service.Close();
                    service = null;
                }
            });
            this.m_Services.Clear();
            this.m_Services = null;

            this.SetText(this.tsslbStauts, "服务未启动");

            this.tsmiStart.Enabled = true;
            this.tsmiStop.Enabled = false;
            this.tsmiStart2.Enabled = true;
            this.tsmiStop2.Enabled = false;
        }

        /// <summary>
        /// 初始化服务
        /// </summary>
        private void InitServices()
        {
            this.m_Services = new List<ServiceHost>();

            // 文件传输服务
            TransportFileService transportFileService = new TransportFileService()
            {
                GetSaveDirectory = this.GetSaveDir,
                GetBufferSize = this.GetBufSize
            };
            transportFileService.TransReady += new EventHandler<TransReadyEventArgs>(TransportFileService_TransReady);
            transportFileService.TransProgressChanged += new EventHandler<TransProgressChangedEventArgs>(TransportFileService_TransProgressChanged);
            transportFileService.TransCompleted += new EventHandler<TransCompletedEventArgs>(TransportFileService_TransCompleted);
            ServiceHost transportFileServiceHost = new ServiceHost(transportFileService);
            transportFileServiceHost.Opened += (sender, e) =>
            {
                this.AppendText(this.txtMsg, string.Format("{0} 传输服务已开启.\r\n", DateTime.Now));
            };
            transportFileServiceHost.Closed += (sender, e) =>
            {
                this.AppendText(this.txtMsg, string.Format("{0} 传输服务已关闭.\r\n", DateTime.Now));
            };

            ServiceHost driveServiceHost = new ServiceHost(typeof(DriveService));
            driveServiceHost.Opened += (sender, e) =>
            {
                this.AppendText(this.txtMsg, string.Format("{0} 驱动器服务已开启.\r\n", DateTime.Now));
            };
            driveServiceHost.Closed += (sender, e) =>
            {
                this.AppendText(this.txtMsg, string.Format("{0} 驱动器服务已关闭.\r\n", DateTime.Now));
            };

            ServiceHost upgradeServiceHost = new ServiceHost(typeof(UpgradeService));
            upgradeServiceHost.Opened += (sender, e) =>
             {
                 this.AppendText(this.txtMsg, string.Format("{0} 应用程序更新服务已开启.\r\n", DateTime.Now));
             };
            upgradeServiceHost.Closed += (sender, e) =>
            {
                this.AppendText(this.txtMsg, string.Format("{0} 应用程序更新服务已关闭.\r\n", DateTime.Now));
            };

            //MCUService mcuService = new MCUService()
            //{
            //    GetSaveDirectory = this.GetSaveDir,
            //    GetBufferSize = this.GetBufSize
            //};
            //mcuService.TransReady += TransportFileService_TransReady;
            //mcuService.TransProgressChanged += TransportFileService_TransProgressChanged;
            //mcuService.TransCompleted += new EventHandler<TransCompletedEventArgs>(MCUService_TransCompleted);
            //ServiceHost mcuServiceHost = new ServiceHost(mcuService);
            //mcuServiceHost.Opened += (sender, e) =>
            //{
            //    this.AppendText(this.txtMsg, string.Format("{0} 单片机服务已开启.\r\n", DateTime.Now));
            //};
            //mcuServiceHost.Closed += (sender, e) =>
            //{
            //    this.AppendText(this.txtMsg, string.Format("{0} 单片机服务已关闭.\r\n", DateTime.Now));
            //};

            m_Services.Add(transportFileServiceHost);
            m_Services.Add(driveServiceHost);
            m_Services.Add(upgradeServiceHost);
            //m_Services.Add(mcuServiceHost);
        }
        #endregion

        #region 单片机相关事件

        void MCUService_TransCompleted(object sender, TransCompletedEventArgs e)
        {
            string path = Path.Combine(this.GetSaveDir(), "MCU\\Upgrade.dat");
            switch (e.TransAction)
            {
                case TransportAction.Upload:
                    this.m_UploadFileCollection.TransFileCompleted(e);

                    FileHelper.CreateDir(path);
                    using (StreamWriter sw = new StreamWriter(path))
                    {
                        sw.WriteLine(e.FullPath);
                    }
                    break;
                case TransportAction.UploadFaultLog:
                    this.m_UploadFileCollection.TransFileCompleted(e);
                    this.AppendText(this.txtMsg, string.Format("{0} {1} 故障文件传输完毕.\r\n", DateTime.Now, e.RelativePath));
                    using (FaultFile failureFile = new FaultFile(e.FullPath))
                    {
                        failureFile.AfterCompleted = (o) =>
                        {
                            if (o.Error != null)
                            {
                                this.AppendText(this.txtMsg,
                                    string.Format("{0} 故障文件 {1} 解析、入库时发生错误。错误信息：\r\n{2}\r\n", DateTime.Now, o.FilePath, o.Error.Message));
                            }

                            if (o.HasRecord)
                            {
                                //MessageBox.Show("接收到远程单片机发送的故障信息，请联系维护人员处理。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                this.Invoke((MethodInvoker)delegate { this.m_FailureDlg.Show(); });
                            }
                        };
                        failureFile.Start();
                    }
                    break;
                case TransportAction.Download:
                    this.m_DownloadFileCollection.TransFileCompleted(e);
                    try
                    {
                        if (File.Exists(path))
                        { File.Delete(path); }

                        if (File.Exists(e.FullPath))
                        { File.Delete(e.FullPath); }
                    }
                    catch (Exception)
                    { }
                    break;
                default:
                    break;
            }

            this.AppendText(this.txtMsg, string.Format("{0} {1} 单片机相关传输完毕.\r\n", DateTime.Now, e.RelativePath));
        }

        #endregion


        void TransportFileService_TransCompleted(object sender, TransCompletedEventArgs e)
        {
            switch (e.TransAction)
            {
                case TransportAction.Upload:
                    this.m_UploadFileCollection.TransFileCompleted(e);
                    break;
                case TransportAction.UploadFaultLog:
                    break;
                case TransportAction.Download:
                    this.m_DownloadFileCollection.TransFileCompleted(e);
                    break;
                default:
                    break;
            }

            this.AppendText(this.txtMsg, string.Format("{0} {1} 传输完毕.\r\n", DateTime.Now, e.RelativePath));
        }

        void TransportFileService_TransProgressChanged(object sender, TransProgressChangedEventArgs e)
        {
            switch (e.TransAction)
            {
                case TransportAction.Upload:
                case TransportAction.UploadFaultLog:
                    this.m_UploadFileCollection.TransFileProgressChanged(e.RelativePath, e.ProgressPercentage);
                    break;
                case TransportAction.Download:
                    this.m_DownloadFileCollection.TransFileProgressChanged(e.RelativePath, e.ProgressPercentage);
                    break;
                default:
                    break;
            }

            this.AppendText(this.txtMsg, string.Format("{0} {1} 传输进度：{2}%.\r\n", DateTime.Now, e.RelativePath, e.ProgressPercentage));
        }

        void TransportFileService_TransReady(object sender, TransReadyEventArgs e)
        {
            TransFileItem item = new TransFileItem()
            {
                IP = e.IP,
                Name = Path.GetFileName(e.RelativePath),
                RelativePath = e.RelativePath,
                FileSize = FileHelper.FormatFileSize(e.FileLength),
                Length = e.FileLength,
                ProgressPercentage = string.Format("{0}%", e.ProgressPercentage),
                Status = TransStatus.Waiting
            };
            switch (e.TransAction)
            {
                case TransportAction.Upload:
                case TransportAction.UploadFaultLog:
                    this.dgvUploadFiles.Invoke(new Action<TransFileItem>(this.m_UploadFileCollection.Add), new object[] { item });
                    break;
                case TransportAction.Download:
                    this.dgvDownloadFiles.Invoke(new Action<TransFileItem>(this.m_DownloadFileCollection.Add), new object[] { item });
                    break;
                default:
                    break;
            }
        }

        private void tsmiStart_Click(object sender, EventArgs e)
        {
            Start();
        }

        private void tsmiStop_Click(object sender, EventArgs e)
        {
            Stop();
        }

        private void FormVisible_Click(object sender, EventArgs e)
        {
            if (this.Visible)
            {
                this.Hide();
                this.NotifyIcon1.Visible = true;
            }
            else
            {
                this.Show();
                this.NotifyIcon1.Visible = false;
            }
        }

        private void tsmiExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void NotifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.tsmiShow.PerformClick();
        }

        private void tsmiSetting_Click(object sender, EventArgs e)
        {
            FrmSetting frmSetting = new FrmSetting();
            frmSetting.ShowDialog();
        }

        private void tsbtnClearUploadCmp_Click(object sender, EventArgs e)
        {
            this.m_UploadFileCollection.ClearCompleted();
        }

        private void tsbtnClearDownloadCmp_Click(object sender, EventArgs e)
        {
            this.m_DownloadFileCollection.ClearCompleted();
        }








    }
}
